package com.lhd.component;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.lhd.entity.constants.Constants;
import com.lhd.entity.dto.AdditionInfoDto;
import com.lhd.entity.dto.UserDto;
import com.lhd.entity.po.User;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * @Author: liuhd
 * @Date: 2025/3/16 22:33
 * @Description:
 */
@Component
public class RedisComponent {
    @Resource
    private RedisTemplate<String, Object> redisTemplate;

    private void setValue(String key, Object value) {
        redisTemplate.opsForValue().set(key, value);
    }

    private void setValue(String key, Object value, Integer time, TimeUnit timeUnit) {
        redisTemplate.opsForValue().set(key, value, time, timeUnit);
    }

    private Object getValue(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    private void deleteKey(String key){
        // 检查key是否存在
        Boolean hasKey = redisTemplate.hasKey(key);
        if (hasKey != null && hasKey) {
            // 如果key存在，则删除它
            redisTemplate.delete(key);
        }
    }

    // 新增用户Dto
    public void saveUserInfoToken(UserDto userDto) {
        // 删除原来的
        cleanToken();

        String uuid = IdUtil.simpleUUID();
        userDto.setToken(uuid);

        String key = Constants.REDIS_KEY + Constants.TOKEN + uuid;

        setValue(key, userDto, Constants.ONE_WEEK_H, TimeUnit.HOURS);
    }

    // 获取用户Dto
    public UserDto getUserInfoDto(String key) {
        Map<String, Object> map = (Map<String, Object>) getValue(key);
        UserDto userDto = new UserDto();
        BeanUtil.fillBeanWithMap(map, userDto, true);
        return userDto;
    }

    // 删除用户token
    private void cleanToken(){
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            // 从cookie中取出token
            String token = null;
            Cookie[] cookies = request.getCookies();
            if (cookies != null) {
                for (Cookie cookie : cookies) {
                    if (cookie.getName().equals("token")) {
                        token = cookie.getValue();
                        break;
                    }
                }
                // 从redis中删除这个用户的token
                if (!StrUtil.isBlank(token)) {
                    deleteKey(Constants.REDIS_KEY + Constants.TOKEN + token);
                }
            }
        }
    }



    /**
     * @description: 将发布签到的额外信息存入redis
     * @param additionInfoDto 额外信息
     * @param aid 活动id
     * @param lastTime 持续时间
     * @return
     * @author liuhd
     * 2025/3/24 14:32
     */
    public void saveAdditionInfo(AdditionInfoDto additionInfoDto, Integer aid, Integer lastTime,String infix) {
        String key = Constants.REDIS_KEY + infix + ":" + aid;
        setValue(key,additionInfoDto,lastTime,TimeUnit.MINUTES);
    }


    /**
     * @param code
     * @param email
     * @return
     * @description: 将邮箱的验证码保存到redis
     * @author liuhd
     * 2025/3/24 15:45
     */
    public void saveMailCode(String email,String code) {
        setValue(Constants.REDIS_KEY + Constants.MAIL_CODE + email,code,Constants.TEN,TimeUnit.MINUTES);
    }

    public String getMailCode(String email) {
        return (String) getValue(Constants.REDIS_KEY + Constants.MAIL_CODE + email);
    }

    /**
     * @description: 修改用户信息
     * @param newUserDto
     * @param oldUserDto
     * @return
     * @author liuhd
     * 2025/3/24 16:12
     */

    public void updateUserDto(UserDto newUserDto, UserDto oldUserDto) {
        // 构建 Redis Key
        String redisKey = Constants.REDIS_KEY + Constants.TOKEN + oldUserDto.getToken();


        // 将旧的和新的用户信息转换为 Map
        Map<String, Object> oldMap = BeanUtil.beanToMap(oldUserDto);
        Map<String, Object> newMap = BeanUtil.beanToMap(newUserDto);

        // 遍历新用户信息的 Map，更新非空字段
        for (Map.Entry<String, Object> entry : newMap.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (ObjectUtil.isNotEmpty(value)) { // 严格检查非空
                oldMap.put(key, value);
            }
        }

        // 将更新后的 Map 转换回 UserDto 对象
        UserDto updatedUserDto = new UserDto();
        BeanUtil.fillBeanWithMap(oldMap, updatedUserDto, false);

        // 保存更新后的用户信息到 Redis
        setValue(redisKey,updatedUserDto,Constants.ONE_WEEK_H,TimeUnit.HOURS);
    }

    /**
     * @description: 通用存储
     * @param key
     * @param value
     * @return
     * @author liuhd
     * 2025/4/12 14:11
     */
    public void setCommon(String key, Object value,Integer time, TimeUnit timeUnit) {
        setValue(key,value,time,timeUnit);
    }
    public void setCommon(String key, Object value) {
        setValue(key,value);
    }

    /**
     * @description: 通用取值，需要手动转成bean
     * @param key
     * @return java.util.Map
     * @author liuhd
     * 2025/4/12 15:07
     */
    public Map getCommonMap(String key){
        return (Map<String, Object>) getValue(key);
    }
    /**
     * @description: 通用取值
     * @param key
     * @return java.lang.String
     * @author liuhd
     * 2025/4/12 15:15
     */

    public String getCommonString (String key){
        Object value = getValue(key);
        return (String) value;
    }
}
